home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / workbnch / flist12.2 < prev    next >
Text File  |  1989-03-15  |  52KB  |  1,956 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i050:  flist - scrollable cli and directory lister v1.2, Part02/03
  5. Message-ID: <12229@swan.ulowell.edu>
  6. Date: 15 Mar 89 17:22:32 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1945
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: alliant!mistress!berry (Steve -Raz- Berry)
  12. Posting-number: Volume 89, Issue 50
  13. Archive-name: workbench/flist12.2
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    menu.c
  23. #    parse.c
  24. #    pathname.c
  25. #    readme
  26. #    rexxglue.asm
  27. #    rexxport.c
  28. # This archive created: Wed Mar 15 12:12:37 1989
  29. cat << \SHAR_EOF > menu.c
  30. /**************************************************************************
  31. *     M E N U   E X A M P L E    P R O G R A M   -   JOHN DRAPER
  32. *   (originally it was anyway)
  33. *
  34. *  Modified (mangled) by Steve Berry 7/77/88
  35. *
  36. ***************************************************************************/
  37.  
  38. #include <libraries/arpbase.h>
  39. #include "flist.h"
  40.  
  41. void *OpenLibrary();
  42. struct Window *OpenWindow();
  43. struct IntuiMessage *GetMsg();
  44. struct Window *BuildSysRequest();
  45. extern void Cleanup(),scrprt(),getkey();
  46. extern struct Gadget pg;
  47. extern struct Window *winptr;
  48.  
  49. extern struct IntuiText TRUEtext;
  50. extern struct Window *winptr;
  51. extern struct Screen *scrptr;
  52. extern struct RastPort *rp;
  53. extern struct FileLock *lock, olddir;
  54. extern long line, numfiles, collum, first;
  55. extern char (*fname[MAXDIR])[FCHARS];
  56. extern char (*finfo[MAXDIR])[4];
  57. extern char conline[256];
  58. long top;
  59.  
  60. /***************************************************************************
  61.                      M E N U      D E F I N I T I O N S
  62. ***************************************************************************/
  63.  
  64. #define NUM_MENUS 3
  65.  
  66. /* Copies of this structure will get "stamped" into many more */
  67. /* Allocated later */
  68.  
  69. struct IntuiText generic = {
  70.   0, 1,                        /* Bluepen, Whitepen */
  71.   JAM2, 5,                     /* mode,  LeftEdge */
  72.   0, NL,                       /* Top (to be filled later), Font */
  73.   NL,                          /* Name (to be filled later) */
  74.   NL                           /* Next one */
  75. };
  76.  
  77. /* Menu numbers */
  78.  
  79. #define PROJ_MENU 0
  80. #define DIR_MENU  1
  81. #define SORT_MENU 2
  82.  
  83. /* Menu Widths */
  84.  
  85. #define FIL_WIDTH   80
  86. #define DIR_WIDTH   100
  87. #define SORT_WIDTH  120
  88. #define ITEM_WIDTH  150
  89. #define REQ_WIDTH   100
  90.  
  91. int item_widths[ NUM_MENUS ] = {150,250,150};
  92.  
  93. /* All items in these menus has the following flags set */
  94.  
  95. #define BOX_FILL    ITEMTEXT | ITEMENABLED | HIGHBOX     
  96. #define BLACK_FILL  COMMSEQ | ITEMTEXT | ITEMENABLED | HIGHCOMP
  97. #define HAS_CHECKS  COMMSEQ | ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT
  98.  
  99.                             /** FILE MENU ITEMS  **/
  100. #define NUM_FILE_ITEMS  4
  101. #define DO_ITEM         0
  102. #define ICON_ITEM       1
  103. #define ABOUT_ITEM      2
  104. #define QUIT_ITEM       3
  105.  
  106. struct MenuItem  file_items[NUM_FILE_ITEMS];
  107. struct IntuiText file_names[NUM_FILE_ITEMS];
  108.  
  109. char  *filemenu_names[] = {
  110.    "Execute REXX",
  111.    "Iconify",
  112.    "About",
  113.    "Quit"
  114. };
  115.  
  116. char *filemenu_short[] = {
  117.     "E",
  118.     "I",
  119.     "B",
  120.     "Q"
  121. };
  122.  
  123. struct Menu fmenu = {
  124.   NL,                        /* Pointer to next menu, fill in later */
  125.   0, 0, FIL_WIDTH, 10,       /* LeftEdge, TopEdge, Width, Height */
  126.   MENUENABLED,               /* FLAGS */
  127.   "Project",                 /* Menu name */
  128.   NL                         /* First item structure */
  129. };
  130.  
  131. /************ Next menu ****************/
  132.  
  133.                             /** FILE MENU ITEMS  **/
  134. #define NUM_DIR_ITEMS   7
  135. #define PARENT_ITEM     0
  136. #define CHANGE_ITEM     1
  137. #define ARP_ITEM        2
  138. #define REGET_ITEM      3
  139. #define KILL_ITEM       4
  140. #define RENAME_ITEM     5
  141. #define MAKEDIR_ITEM    6
  142.  
  143. struct MenuItem  dir_items[NUM_DIR_ITEMS];
  144. struct IntuiText dir_names[NUM_DIR_ITEMS];
  145.  
  146. char  *dirmenu_names[] = {
  147.     "  Parent Directory",
  148.     "  Change Directory",
  149.     "  ARP Change to Volume",
  150.     "  Get Directory",
  151.     "  Kill File",
  152.     "  Rename File",
  153.     "  Make Dir"
  154. };
  155.  
  156. char *dirmenu_short[] = {
  157.     "P",
  158.     "D",
  159.     "A",
  160.     "G",
  161.     "K",
  162.     "R",
  163.     "N"
  164. };
  165.  
  166. struct Menu dmenu = {
  167.   NL,                        /* Pointer to next menu, fill in later */
  168.   100, 0, DIR_WIDTH, 10,     /* LeftEdge, TopEdge, Width, Height */
  169.   MENUENABLED,               /* FLAGS */
  170.   "Directory",               /* Menu name */
  171.   NL                         /* First item structure */
  172. };
  173.  
  174. /************ Next menu ****************/
  175.  
  176.                             /** FILE MENU ITEMS  **/
  177. #define NUM_SORT_ITEMS  5
  178. #define ALPHABET_ITEM   0
  179. #define SIZE_ITEM       1
  180. #define TIME_ITEM       2
  181. #define PATTERN_ITEM    3
  182. #define DAY_ITEM        4
  183.  
  184. struct MenuItem  sort_items[NUM_SORT_ITEMS];
  185. struct IntuiText sort_names[NUM_SORT_ITEMS];
  186.  
  187. char  *sortmenu_names[] = {
  188.     "Alphabeticly",
  189.     "By Size",
  190.     "By Time",
  191.     "By Pattern",
  192.     "By Day"
  193. };
  194.  
  195. char *sortmenu_short[] = {
  196.     "S",
  197.     "Z",
  198.     "T",
  199.     "O",
  200.     "Y"
  201. };
  202.  
  203. struct Menu smenu = {
  204.   NL,                        /* Pointer to next menu, fill in later */
  205.   200, 0, SORT_WIDTH, 10,    /* LeftEdge, TopEdge, Width, Height */
  206.   MENUENABLED,               /* FLAGS */
  207.   "Sort List",           /* Menu name */
  208.   NL                         /* First item structure */
  209. };
  210.  
  211. /***************************************************************************
  212.                    AUTO REQUEST INTUITEXT STRUCTURES
  213. ***************************************************************************/
  214.  
  215. struct IntuiText Auto3 = {
  216.    REDP,  WHTP,
  217.    JAM1,  15,
  218.    35,    NL,
  219.    "Freely Redistributable for noncomercial purposes. ", NULL
  220. };
  221.  
  222. struct IntuiText Auto2 = {
  223.    REDP,  WHTP,
  224.    JAM1,  15,
  225.    17,    NL,
  226.    " Inspired by the PD Flist on IBM mainframes ", &Auto3
  227. };
  228.  
  229. struct IntuiText AboutText = {
  230.    REDP,  WHTP,
  231.    JAM1,  20,
  232.    5,    NL,
  233.    " Flist was written by Steve (Raz) Berry ", &Auto2  
  234. };
  235.  
  236. /***************************************************************************
  237.                   M A I N     P R O G R A M     M O D U L E
  238. ***************************************************************************/
  239. long mousey, mousex;
  240.  
  241. menu()
  242. {
  243.     ULONG    class;     /* Message class from Intuition                  */
  244.     USHORT   code;      /* Menu code info from Intuition                 */
  245.     struct MenuItem *item;
  246.     long     gadown=FALSE;
  247.     struct IntuiMessage *message;
  248.     struct Gadget *igad;
  249.     register short  prevy=0;
  250.     register int i,temp;
  251.     char buf[256];
  252.  
  253.     mousey = 0;
  254.     mousex = 0;
  255.  
  256.     fmenu.FirstItem = &file_items[0];
  257.     fmenu.NextMenu = &dmenu;
  258.     dmenu.NextMenu = &smenu;
  259.  
  260.     NewMenu( &fmenu, filemenu_names, filemenu_short, file_items, file_names,
  261.             NUM_FILE_ITEMS, item_widths[0], BLACK_FILL);
  262.  
  263.     dmenu.FirstItem = &dir_items[0];
  264.  
  265.     NewMenu( &dmenu, dirmenu_names, dirmenu_short, dir_items, dir_names,
  266.             NUM_DIR_ITEMS, item_widths[1], HAS_CHECKS);
  267.  
  268.     smenu.FirstItem = &sort_items[0];
  269.  
  270.     NewMenu( &smenu, sortmenu_names, sortmenu_short, sort_items, sort_names,
  271.             NUM_SORT_ITEMS, item_widths[2], BLACK_FILL);
  272.  
  273. /*    sort_items[0].MutualExclude = 0xfffe; */
  274.  
  275.     top = 0;     /* this is the pointer to the first file on the screen */
  276.   
  277.     SetMenuStrip(winptr, &fmenu);      /* Set up the menu here */
  278.  
  279.     ShowTitle(scrptr,TRUE);      /* Do show the screen Title. */
  280.  
  281.     sort(0);                     /* sort the list alphabetically */
  282.     refresh();
  283.     drawcur();
  284.  
  285.     for (;;)
  286.     {
  287.       if ((message = (struct IntuiMessage *)GetMsg(winptr->UserPort)) == 0L)  {
  288.           Wait(1L<<winptr->UserPort->mp_SigBit);
  289.           continue;
  290.       }
  291.  
  292.         class = message->Class;
  293.         code = message->Code;
  294.         igad = (struct Gadget *)message->IAddress;
  295.         mousey = message->MouseY;
  296.         mousex = message->MouseX;
  297.  
  298.         switch (class) {
  299.  
  300.             case RAWKEY:
  301.                 getkey(message);    /* message is replied to in routine */
  302.                 break;          
  303.  
  304.             case MOUSEMOVE: 
  305.                 ReplyMsg(message);
  306.                 if(gadown){
  307. #ifdef KILLEXTRA
  308.                         /* get rid of any extra messages */
  309.  
  310.                         while((message = (struct IntuiMessage *)GetMsg(winptr->UserPort)) != 0L) {
  311.                                 mousey = message->MouseY;
  312.                                 ReplyMsg(message);
  313.                                 if((prevy<mousey)&&(line<numfiles))
  314.                                 top++;
  315.                                 if((prevy>mousey)&&(top>0))
  316.                                         top--;
  317.                                 prevy = mousey;  
  318.                         } 
  319. #endif
  320.                         if((prevy<mousey)&&(line<numfiles-1)){
  321.                                         line++;
  322.                                         top++;
  323.                         }
  324.                         if((prevy>mousey)&&(top>0)){
  325.                                 if (line>0)
  326.                                         line--;
  327.                                 top--;
  328.                         }
  329.                         prevy = mousey;    
  330.                         temp = numfiles-top;
  331.                         scrprt(temp,top);
  332.                 }
  333.                 break;
  334.                 
  335.         case GADGETUP: 
  336.                 ReplyMsg(message);
  337.                 drawline(collum,TRUE);
  338.                 drawcur();
  339.                 gadown = FALSE;
  340.                 break;
  341.  
  342.         case GADGETDOWN:
  343.                 ReplyMsg(message);
  344.                 blankcur();
  345.                 switch ( i = igad->GadgetID) {
  346.                     case FGAD: /* the prop gadget here... */
  347.                         gadown = TRUE;
  348.                         strcpy(buf,conline);
  349.                         conline[first] = 0;
  350.                         drawline(collum,TRUE);
  351.                         strcpy(conline,buf);
  352.                         drawline(collum,TRUE);
  353.                         break;
  354.                 }
  355.                 break;
  356.  
  357.         case CLOSEWINDOW: 
  358.                 ReplyMsg(message);
  359.                 Cleanup();
  360.                 exit(0);
  361.                 break;
  362.  
  363.         case MENUPICK:
  364.                 ReplyMsg(message);
  365.                 blankcur();
  366.                 while (code != MENUNULL) {
  367. #ifdef DEBUG
  368.     sprintf(buf,"Code is %ld Menunum is %ld",code, MENUNUM(code));
  369.     auto_req(buf);
  370. #endif
  371.                     domenu(MENUNUM(code), ITEMNUM(code),
  372.                         SUBNUM(code));
  373.                     item = ItemAddress(&fmenu, MENUNUM(code));
  374.                     if (item->NextSelect == code)
  375.                         break;
  376.                     code = item->NextSelect;
  377.                     item->NextSelect = MENUNULL;
  378.                 }
  379.                 drawcur();
  380.                 break;
  381.  
  382.         case MOUSEBUTTONS: 
  383.                 ReplyMsg(message);
  384.                 break;
  385.  
  386.         }   /* Case */
  387.    }  /* for */
  388. }   /* End of Main */
  389.  
  390. /***************************************************************************
  391.                    C R E A T E    A    N E W    M E N U
  392. ***************************************************************************/
  393. NewMenu ( menu, item_names,  item_short, menu_items, menu_text, 
  394.         num_items, Mwidth, flag)
  395.  
  396. struct Menu      *menu;           /* Menu structure                       */
  397. char             *item_names[];   /* Pointer to array of item names       */
  398. char             *item_short[];   /* Pointer to array of shortcut char    */
  399. struct MenuItem  menu_items[];    /* pointer to array of structures       */
  400. struct IntuiText menu_text[];     /* Pointer to array of text structures  */
  401. int               num_items;      /* Number of items                      */
  402. int               Mwidth;         /* Menu Width */
  403. long                flag;         /* Special Item flag for ALL items */
  404. {
  405.     int i;
  406.     int height = 0;
  407.  
  408.     for (i=0; i< num_items; i++) {
  409.  
  410.         menu_text[i] = generic;              /* stamp generic template */
  411.         menu_text[i].IText = item_names[i];          /* mv string ptrs */
  412.         menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
  413.         menu_items[i].TopEdge = 10 * i;            /* Top rect of item */
  414.         menu_items[i].LeftEdge = 2;
  415.         menu_items[i].Height = 8;
  416.         menu_items[i].ItemFill = (APTR)&menu_text[i];
  417.         menu_items[i].Width = Mwidth;
  418.         menu_items[i].MutualExclude = 0;
  419.         menu_items[i].Command = item_short[i][0];
  420.         menu_items[i].Flags = (USHORT)flag;
  421.         menu_items[i].SubItem = NULL;
  422.         menu_items[i].NextSelect = MENUNULL;
  423.         height += 10;
  424.     }
  425.     menu_items[num_items-1].NextItem = NULL;
  426.     menu->Height = height;
  427. }
  428.  
  429. /* DO THE MENU SELECTIONS */
  430.  
  431. domenu(menu, item, subitem)
  432. int  menu, item, subitem;
  433. {
  434.     char buf[256];
  435.     int i;
  436.  
  437.     switch (menu) {
  438.  
  439.         case PROJ_MENU: 
  440.             switch (item) {
  441.  
  442.                case  DO_ITEM: 
  443.                     dorexx();
  444.                     break;
  445.  
  446.                case  ICON_ITEM: 
  447.                     tticon();
  448.                     break;
  449.  
  450.                case  QUIT_ITEM:     
  451.                     if(scrptr->FirstWindow->NextWindow != NULL) 
  452.                         auto_req("Kill all other Applications first");
  453.                     else {
  454.                         Cleanup();
  455.                         exit(0);
  456.                     }
  457.                     break;
  458.  
  459.                case  ABOUT_ITEM: 
  460.                     AutoRequest(winptr, &AboutText, &TRUEtext, &TRUEtext, 
  461.                                 0L, 0L, 450L, 80L );
  462.                     break;
  463.             } 
  464.             break;
  465.  
  466.         case DIR_MENU:
  467.  
  468.             for (i=0;i<NUM_DIR_ITEMS;i++)
  469.                 dir_items[i].Flags = HAS_CHECKS;
  470.  
  471.             switch (item) {
  472.  
  473.                 case PARENT_ITEM:
  474.                     parent();
  475.                     refresh();
  476.                     break;
  477.  
  478.                 case CHANGE_ITEM:
  479.                     if (*finfo[line][0] < 0){
  480.                         sprintf(buf,"%s Not a directory",fname[line]);
  481.                         auto_req(buf);
  482.                     }else {
  483.                         changedir(fname[line]);
  484.                         refresh();
  485.                     }
  486.                     break;
  487.  
  488.                 case ARP_ITEM:
  489.                     if (Wbargs() == 0){
  490.                         UnLock(olddir);
  491.                         refresh();
  492.                     }
  493.                     break;
  494.  
  495.                 case REGET_ITEM:
  496.                     getdir();
  497.                     refresh();
  498.                     break;
  499.  
  500.                 case KILL_ITEM:
  501.                     kill(fname[line]);
  502.                     refresh();
  503.                     break;
  504.  
  505.                 case RENAME_ITEM:
  506.                     rename_file(fname[line]);
  507.                     refresh();
  508.                     break;
  509.  
  510.                 case MAKEDIR_ITEM:
  511.                     make_dir();
  512.                     refresh();
  513.                     break;
  514.             }
  515.             break;
  516.  
  517.         case SORT_MENU:
  518.         
  519.             switch (item) {
  520.  
  521.                 case ALPHABET_ITEM:
  522.                     sort(0);
  523.                     refresh();
  524.                     break;
  525.  
  526.                 case SIZE_ITEM:
  527.                     sort(1);
  528.                     refresh();
  529.                     break;
  530.  
  531.                 case TIME_ITEM:
  532.                     sort(2);
  533.                     refresh();
  534.                     break;
  535.  
  536.                 case PATTERN_ITEM:
  537.                     sort(3);
  538.                     refresh();
  539.                     break;
  540.  
  541.                 case DAY_ITEM:
  542.                     sort(4);
  543.                     refresh();
  544.                     break;
  545.  
  546.             }
  547.             break;
  548.     }
  549. }
  550.  
  551. SHAR_EOF
  552. cat << \SHAR_EOF > parse.c
  553. /*
  554. * parse routines for flist...
  555. *
  556. * uses arp functions.
  557. *
  558. */
  559.  
  560. #include <libraries/arpbase.h>
  561. #include <stdio.h>
  562. #include "flist.h"
  563.  
  564. /* Global stuff for ARP */
  565.  
  566. char *CLI_Template = ",FROM/K";
  567. char *CLI_Help = "Type filename(s) or FROM and a file with name of files";
  568.  
  569. /* global flist stuff */
  570.  
  571. struct AnchorPath *ap = NULL;
  572.  
  573. long (*finfo[MAXDIR])[4];  /* miscelaneous info -- file size,blocks,dir type etc... */
  574. char (*fname[MAXDIR])[FCHARS];     /* file name and comment */
  575. char (*comm[MAXDIR])[FCHARS];
  576. char (*fstring[MAXDIR])[LEN_DATSTRING];
  577. char (*ftime[MAXDIR])[LEN_DATSTRING];
  578.  
  579. struct FileLock *startdir = NULL, *lock = NULL, *olddir = NULL;
  580.  
  581. long numfiles,getcurrentdir();
  582.  
  583. long parse(argc,argv)
  584. long argc;
  585. char *argv[];
  586. {
  587.     long i,rc = -99;
  588.     
  589.     for (i=0;i<MAXDIR;i++)  /* zero out the memory arrays */
  590.         fname[i] = 0;
  591.  
  592.     ap = (struct AnchorPath *)ArpAllocMem(sizeof(struct AnchorPath),FAST);
  593.  
  594.     if(ap == NULL)
  595.         return OUT_OF_MEMORY;
  596.  
  597.     ap->ap_BreakBits = SIGBREAKB_CTRL_C;
  598.     ap->ap_Length = 0;
  599.  
  600.     if((argv[1] != 0) && (argc > 0)){
  601.         if(!getcurrentdir(argv[1]))
  602.             return -98;
  603.         strcat(argv[1],"*");
  604.         rc = FindFirst(argv[1],ap);
  605.         if(rc == NULL)
  606.             rc = Fillarray();
  607.     }
  608.     else{ 
  609.         if ((argc > 1) && (argv[2] != NULL))
  610.             rc = other_input(argv[2]);
  611.         else{
  612.             if(argc == 0)  
  613.                 rc = Wbargs();   /* do we have Workbench? */
  614.             else{
  615.                 if(!getcurrentdir(""))
  616.                         return -98;
  617.                 rc = FindFirst("*",ap); /* user only typed 'flist' */
  618.                 if(rc == NULL)          /* so we are going to give him the */
  619.                     rc = Fillarray();   /* current directory */
  620.             }
  621.         }
  622.     }
  623.     return rc;    /* return code should always be sent */
  624. }
  625.  
  626. FreeFlistMem()
  627. {
  628.     if(ap != NULL )
  629.         FreeAnchorChain(ap);
  630. }
  631.  
  632. /* Stuff all the filenames and pertinent information into */
  633. /* the flist arrays */
  634.  
  635. long Fillarray()
  636. {
  637.     long rc = NULL;
  638.     struct DateTime dt;
  639.     int i;
  640.  
  641.     numfiles = 0;
  642.  
  643.     dt.dat_Format = FORMAT_DOS;
  644.     dt.dat_StrDay = NULL;
  645.     dt.dat_Flags = DTB_SUBST;
  646.  
  647.     while(rc != ERROR_NO_MORE_ENTRIES){
  648.  
  649.         if(get_array_mem(numfiles) == OUT_OF_MEMORY)
  650.                 return OUT_OF_MEMORY;
  651.                 
  652.         strcpy(fname[numfiles],&ap->ap_Info.fib_FileName);
  653.         strcpy(comm[numfiles],&ap->ap_Info.fib_Comment); 
  654.         dt.dat_Stamp = ap->ap_Info.fib_Date;
  655.         dt.dat_StrDate = fstring[numfiles];
  656.         dt.dat_StrTime = ftime[numfiles];
  657.  
  658.         (*finfo[numfiles])[0] = ap->ap_Info.fib_DirEntryType;
  659.         (*finfo[numfiles])[1] = ap->ap_Info.fib_Protection;
  660.         (*finfo[numfiles])[2] = ap->ap_Info.fib_Size;
  661.         (*finfo[numfiles])[3] = ap->ap_Info.fib_NumBlocks;
  662.  
  663.         if((rc = StamptoStr(&dt)) != NULL)
  664.                 break;
  665.  
  666.         rc = FindNext(ap);
  667.  
  668.         if( ++numfiles > MAXDIR || rc != NULL)
  669.             break;
  670.     }
  671.  
  672.     for (i=numfiles;i<MAXDIR;i++)   /* free all array memory not being used */
  673.         if (fname[i] != 0) {
  674.             FreeMem(fname[i],FCHARS);
  675. /*            FreeMem(comm[i],FCHARS); */
  676.             FreeMem(finfo[i],16L);
  677.             FreeMem(fstring[i],LEN_DATSTRING);
  678.             FreeMem(ftime[i],LEN_DATSTRING);
  679.             fname[i] = 0;
  680.             finfo[i] = 0;
  681.             fstring[i] = 0;
  682.             ftime[i] = 0;
  683.         }
  684.  
  685.     if(rc == ERROR_NO_MORE_ENTRIES)
  686.         return NULL;
  687.     return rc;
  688. }
  689.  
  690. /* The user has not supplied any filenames or input for the File */
  691. /* template. Here we check for the optional FROM keyword. */
  692.  
  693. long other_input(argv)
  694. char *argv[];
  695. {
  696.  
  697.     FILE *fp;
  698.     char *buffer;
  699.     struct DateTime dt;
  700.     register long rc;
  701.     int i;
  702.  
  703.     if ((buffer = (char *)ArpAllocMem(LINESIZE,FAST)) == NULL)
  704.         return OUT_OF_MEMORY;
  705.  
  706.     if ((fp = fopen(argv,"r")) == NULL)
  707.         return -99L;
  708.  
  709.     if (!getcurrentdir(""))
  710.         return -98L;
  711.  
  712.     dt.dat_Format = FORMAT_USA;
  713.     dt.dat_StrDay = NULL;
  714.     dt.dat_Flags = DTB_SUBST;
  715.  
  716.     numfiles = 0;
  717.     while (feof(fp) == NULL){
  718.  
  719.         if(get_array_mem(numfiles) == OUT_OF_MEMORY)
  720.                 return OUT_OF_MEMORY;
  721.                 
  722.         fscanf(fp,"%s",buffer);
  723.         rc = FindFirst(buffer,ap);
  724.         if (rc != NULL )
  725.             break;
  726.  
  727.         strcpy(fname[numfiles],buffer);
  728.         strcpy(comm[numfiles],&ap->ap_Info.fib_Comment); 
  729.         (*finfo[numfiles])[0] = ap->ap_Info.fib_DirEntryType;
  730.         (*finfo[numfiles])[1] = ap->ap_Info.fib_Protection;
  731.         (*finfo[numfiles])[2] = ap->ap_Info.fib_Size;
  732.         (*finfo[numfiles])[3] = ap->ap_Info.fib_NumBlocks;
  733.         dt.dat_Stamp = ap->ap_Info.fib_Date;
  734.         dt.dat_StrDate = fstring[numfiles];
  735.         dt.dat_StrTime = ftime[numfiles];
  736.  
  737.         if((rc = StamptoStr(&dt)) != NULL)
  738.                 break;
  739.  
  740.         if( ++numfiles > MAXDIR | rc != NULL)
  741.             break;
  742.         }
  743.  
  744.     if (feof(fp) == NULL){
  745.         if (rc == NULL)
  746.             rc = (LONG)ferror(fp);
  747.     }
  748.     else
  749.         numfiles--;
  750.  
  751.     for (i=numfiles;i<MAXDIR;i++)   /* free all array memory not being used */
  752.         if (fname[i] != 0) {
  753.             FreeMem(fname[i],FCHARS);
  754. /*            FreeMem(comm[i],FCHARS); */
  755.             FreeMem(finfo[i],16L);
  756.             FreeMem(fstring[i],LEN_DATSTRING);
  757.             FreeMem(ftime[i],LEN_DATSTRING);
  758.             fname[i] = 0;
  759.             finfo[i] = 0;
  760.             fstring[i] = 0;
  761.             ftime[i] = 0;
  762.         }
  763.     fclose(fp);
  764.     return rc;        
  765. }
  766.  
  767. long get_array_mem(index)
  768. long    index;
  769. {
  770.  
  771. /* If the memory array already has a block allocated to it return to 
  772.    caller... otherwise allocate one */
  773.  
  774.     if (fname[index] != 0L)
  775.         return 0L;
  776.     
  777.     fname[index] =      (char *)AllocMem(FCHARS,FAST);
  778. /*    comm[index]  =      (char *)AllocMem(FCHARS,FAST); */
  779.     finfo[index] =      (LONG *)AllocMem(16L,FAST);
  780.     fstring[index] =    (char *)AllocMem(LEN_DATSTRING,FAST);
  781.     ftime[index] =      (char *)AllocMem(LEN_DATSTRING,FAST);
  782.  
  783.     if( ftime[index] == NULL | fstring[index] == NULL \
  784.     | fname[index] == NULL | /* comm[index] == NULL | */ finfo[index] == NULL )
  785.         return OUT_OF_MEMORY;
  786.     else
  787.         return 0L;
  788. }
  789.  
  790. /*
  791. ** more Arp stuff for Workbench support
  792. */
  793.  
  794. BYTE dir[DSIZE], name[FCHARS];
  795.  
  796. getarp(mask,fib)
  797. ULONG mask;
  798. struct FileInfoBlock *fib;
  799. {
  800.  
  801.     long rc;
  802.     struct DateTime dt;
  803.  
  804.     dt.dat_Format = FORMAT_USA;
  805.     dt.dat_StrDay = NULL;
  806.     dt.dat_Flags = DTB_SUBST;
  807.  
  808.     strcpy(fname[numfiles],&fib->fib_FileName);
  809.     strcpy(comm[numfiles],&fib->fib_Comment); 
  810.     (*finfo[numfiles])[0] = fib->fib_DirEntryType;
  811.     (*finfo[numfiles])[1] = fib->fib_Protection;
  812.     (*finfo[numfiles])[2] = fib->fib_Size;
  813.     (*finfo[numfiles])[3] = fib->fib_NumBlocks;
  814.     dt.dat_Stamp = ap->ap_Info.fib_Date;
  815.     dt.dat_StrDate = fstring[numfiles];
  816.     dt.dat_StrTime = ftime[numfiles];
  817.  
  818.     if((rc = StamptoStr(&dt)) != NULL)
  819.         return rc;
  820.  
  821.     numfiles++;
  822.  
  823.     return 0L;    /* tell Arp to put this entry in the requester */
  824.  
  825. /* ok, this is the fun part ... cheath told me that there
  826.    is a bug in the handling of the return code. this is the fix. */
  827. #asm
  828.     move.l #0,d0      ; d0 MUST contain the return code 
  829.     move.l d0,4(sp)   ; 4(sp) is the part that gets munged to the 
  830.                       ; correct value 
  831. #endasm
  832. }
  833.  
  834. struct FileRequester arpfr = {
  835.                                      /* Hailing text */
  836.     (BYTE *)"Select a directory, then click on OK.", 
  837.     NULL,                            /* string to put the final name */
  838.     NULL,                            /* string to put the directory entry */
  839.     NULL,                            /* Window for the files */
  840.     NULL,                            /* what calls getarp? */
  841.     NULL,                            /* reserved */
  842.     NULL,                            /* function to be called */
  843.     NULL                             /* reserved */
  844. };
  845.  
  846. long Wbargs()   /* use the arp file requester to get the file names */
  847. {
  848.     long dummy;
  849.     char dname[FCHARS];
  850.  
  851.     strcpy(dir,"RAM:");
  852.     strcpy(dname,"Select directory only.");
  853.  
  854.     arpfr.fr_Dir = dir;
  855.     arpfr.fr_File = dname;
  856.  
  857.     dummy = FileRequest(&arpfr);
  858.  
  859.     if(dummy == NULL)   /* user selects cancel -- so abort */
  860.         return 1;
  861.  
  862.     olddir = lock;      /* save this for later */
  863.  
  864.     if(strcmp(dir,"") == 0)
  865.         getcurrentdir("");
  866.     else {
  867.         lock = Lock(dir,ACCESS_READ);
  868.         if(lock == NULL) {
  869.             auto_req("Can't find requested directory.");
  870.             return 1;
  871.         }
  872.     }
  873.  
  874.     if (startdir == NULL)
  875.         startdir = CurrentDir(lock);
  876.     else
  877.         CurrentDir(lock);
  878.  
  879.     TackOn(dir,"*");
  880.     dummy = FindFirst(dir,ap);
  881.  
  882.     if(dummy == NULL)
  883.        dummy = Fillarray();
  884.  
  885.     return (dummy == NULL || dummy == ERROR_NO_MORE_ENTRIES) ? 0 : 1;
  886. }
  887.  
  888. long getcurrentdir(str)
  889. char *str;
  890. {
  891.     /* This is the only way I have ever been able to reliably get the
  892.        current directory */
  893.     
  894.     /* Save the Value of the Directory we are in now. */
  895.  
  896.     if (str[0] == '\0'){
  897.         struct Process *proc = FindTask(NULL);
  898.  
  899.         lock = DupLock(proc->pr_CurrentDir);
  900.         startdir = CurrentDir(lock);
  901.         return TRUE;
  902.     } else {
  903.         lock = Lock(str);
  904.         startdir = CurrentDir(lock);
  905.         return (startdir == 0) ? FALSE : TRUE;
  906.     }
  907. }
  908. SHAR_EOF
  909. cat << \SHAR_EOF > pathname.c
  910. /** pathname.c
  911. *
  912. *                     Copyright 1988, W.G.J. Langeveld
  913. *                           All Rights Reserved
  914. *                           Freely Distributable
  915. *
  916. *    Expand path name given a lock on a file name. Emulates ARP function
  917. *   of the same name, which is slightly unreliable.
  918. *
  919. *   Mods to device name generation by Steve (Raz) Berry
  920. *   12/31/88 (New Years Eve!)
  921. *
  922. **/
  923.  
  924. #include <stdio.h>
  925.  
  926. char *index();
  927. extern void auto_req();
  928.  
  929. #define FIBSIZ ((long) sizeof(struct FileInfoBlock))
  930.  
  931. int PathName(plock, buffer)
  932. struct FileLock *plock;
  933. char *buffer;
  934. {
  935.    struct FileLock *llock, *curdir;
  936.    char *temp, *pos, buf[100];
  937.    struct FileInfoBlock *filinf;
  938.     long rc;
  939.  
  940.    llock = NULL;
  941.    filinf = NULL;
  942.    temp = NULL;
  943.    buffer[0] = '\0';
  944.  
  945.    filinf = (struct FileInfoBlock *) AllocMem(FIBSIZ, MEMF_PUBLIC|MEMF_CLEAR);
  946.    if (filinf == NULL) goto cleanuplk;
  947.  
  948.    temp = (char *) AllocMem(255L, MEMF_PUBLIC|MEMF_CLEAR);
  949.    if (temp == NULL) goto cleanuplk;
  950.  
  951. #ifdef DEBUG
  952.    if(plock == NULL)
  953.     auto_req("lock is null");
  954. #endif
  955.  
  956.    rc = Examine(plock, filinf);
  957.  
  958.    if (rc == NULL) goto cleanuplk;
  959.  
  960.    strcpy(buffer, filinf->fib_FileName);
  961.    llock = ParentDir(plock);
  962. /*
  963. *  Now loop back through the parent directories until root is found.
  964. *  Meanwhile, keep track of the names.
  965. */
  966.  
  967.    while (llock != NULL) {
  968.       if (Examine(llock, filinf) == NULL) goto cleanuplk;
  969.  
  970.       strcpy(temp, buffer);
  971.       strcpy(buffer, filinf->fib_FileName);
  972.       strcat(buffer, "/");
  973.       strcat(buffer, temp);
  974.  
  975.       curdir = ParentDir(llock);
  976.       UnLock(llock);
  977.       llock = curdir;
  978.    }
  979. /*
  980. *   Now fix up the name
  981. */
  982.  
  983.    if (pos = index(buffer, '/')) {
  984.       *pos = ':';
  985.       if (pos == buffer) {
  986.          strcpy(temp, "ram");
  987.          strcat(temp, buffer);
  988.          strcpy(buffer, temp);
  989.       } 
  990.    } else 
  991.         strcat(buffer, ":");    /* Append : to root names - swb */
  992.  
  993. cleanuplk:
  994.  
  995.    if (filinf != NULL) FreeMem(filinf, FIBSIZ);
  996.    if (temp != NULL)   FreeMem(temp, 255L);
  997.    if (llock != NULL)   UnLock(llock);
  998.  
  999.    return(strlen(buffer));
  1000. }
  1001.  
  1002. SHAR_EOF
  1003. cat << \SHAR_EOF > readme
  1004.  
  1005.                     Flist - The wonder program.
  1006.                            Version 1.2
  1007.                     
  1008.                            Written by :
  1009.                     
  1010.                         Steve (Raz) Berry
  1011.  
  1012. This product may be freely distributed, provided only a nominal fee is 
  1013. charged, and all files are distributed together. This product may NOT be 
  1014. distributed with a commercial product without prior written consent.
  1015.  
  1016. See the end of this file for a list of changes.
  1017.  
  1018. THINGS THAT YOU MUST DO BEFORE RUNNING FLIST:
  1019.  
  1020.     Stack: Set your stack at 10K or so. You can set the stack on Icons
  1021.     if they are project icons. Make sure they are! You will crash the 
  1022.     system if the stack is at the default of 4K.
  1023.  
  1024.     ARP library: This release of Flist requires Version 1.1 of the 
  1025.     arp.library to be placed in you LIBS: directory. ARP may be discontinued
  1026.     for future Flist releases. 
  1027.     
  1028.     Path: The easiest way to insure that Flist knows about your favorite
  1029.     search paths is to set them in your startup-sequence before it exits.
  1030.     (This trick works only under WorkBench 1.3)
  1031.     Otherwise you will have to type the full pathname of each command.
  1032.     One alternate fix is to install a Path-handler to search for your 
  1033.     commands. If you run Flist from the Workbench, you will NOT have any
  1034.     default paths no matter what you do (it's not my fault... really).
  1035.  
  1036.     Install the NULL: device in your system. See the docs in the 
  1037.     distributrion.
  1038.  
  1039. THINGS THAT YOU MUST NOT DO TO RUN FLIST:
  1040.  
  1041.     Using the PD runback command without redirecting the input and output.
  1042.  
  1043.     If you 'run >nil: <nil: flist' and you mount the NULL: device, 
  1044.     then you are safe.
  1045.  
  1046.     If you just type 'runback flist' then there is an increased chance
  1047.     that you will crash your machine. Here's how:
  1048.     
  1049.     Nobody really wants to do this, do they?
  1050.     
  1051.         1) runback flist from the CLI (and don't redirect the output).
  1052.         2) endcli the CLI that spawned flist.
  1053.         3) in Flist type 'run list' and return.
  1054.         4) Hit the left mouse button to continue.
  1055.     
  1056.     The reasons are many and varied as to why, lets just say that the output
  1057.     of the 'run list' was sent to a nonexistant CLI.
  1058.  
  1059.     I suggest that if you want your CLI back, you do:
  1060.  
  1061.         'run <nil: >nil: flist'
  1062.  
  1063.     Use only the 1.3 run command and make sure that the NULL device is 
  1064.     mounted.
  1065.  
  1066.     HINT: If you use a shell, you can make an alias like so:
  1067.  
  1068.         alias fb = "run <nil: >nil: flist []"
  1069.  
  1070.     The NULL device handler is included in the distribution. Read the docs
  1071.     for information on how to install it.
  1072.  
  1073. DESCRIPTION and FEATURES:
  1074.  
  1075.     Flist is a Scrollable, configurable, interactive CLI and LIST combined.
  1076.     ANY command that can be executed in a CLI can be run from Flist.
  1077.     
  1078.     Flist will work in either the Workbench or the CLI environments.
  1079.     
  1080.     You can iconify Flist to get it out of the way (thanks Leo!) and save
  1081.     the price of a 2 bitplane hires screen.
  1082.  
  1083.     Changing directory, changing to a parent directory, Deleting files or
  1084.     directories, using the ARP filerequestor (to change directory) are 
  1085.     builtin functions.
  1086.     
  1087.     Hitting the Escape key will insert the file name (on the current line)
  1088.     into the input area (to the right of the filename).
  1089.  
  1090.     The input area scrolls to the left and right as needed, and allows up to 
  1091.     90 characters per line.
  1092.  
  1093.     Directory entries of up to 999 files are supported.
  1094.  
  1095.     Flist opens windows for execution so it's under the mouse.
  1096.  
  1097.     Sort the list of files alphabetically, by size, by time or by
  1098.     the supplied pattern.
  1099.     
  1100.     If you use snipit, type 'snipit x +3 y +5' to snip from Flist.
  1101.  
  1102.     Need help remembering the keystrokes? Hit the Help key, that's what its
  1103.     there for. You'll get a summary of all of the control sequences that are
  1104.     currently available.
  1105.  
  1106.     Yes there is an AREXX port. It doesn't do too many things at the moment,
  1107.     and you must initiate the conversation, but it's a start. Suggestions
  1108.     on further implementations are welcome.
  1109.  
  1110. FURTHER CONSIDERATIONS:
  1111.  
  1112.     Read the Docs. I mean it. I don't want people sending me e-mail bombs
  1113.     that read like :
  1114.  
  1115.         "I was using your dumb Flist program when it decided to 
  1116.     delete my file when I hit control-k. I though you would get a file
  1117.     requestor or somthing!"
  1118.  
  1119.     Remember, this is only a README. 
  1120.  
  1121. KNOWN BUGS:
  1122.  
  1123.     Sorting by time will sort using the hour of creation only.
  1124.  
  1125.     If you slide the screen down and open a window on the Workbench screen,
  1126.     leaving both screens visible, the window will open on the Flist screen
  1127.     instead of the Workbench.
  1128.  
  1129.     *** This is more interesting than a bug, (in other words I can't fix it)
  1130.     but if you spawn a 'loadwb' (Load Workbench) from Flist, or even when
  1131.     Flist is the frontmost screen, the Amiga workbench takes over the screen
  1132.     permanent like, and uses it for its own. Flist remains running but
  1133.     can't be terminated.
  1134.  
  1135.     Fifteen color Pointer animations change the workbench screen colors to 
  1136.     those matching Flist.
  1137.  
  1138.     Not so configurable in this release. Sorry.
  1139.  
  1140.     Still haven't allowed for any screen size other than 640x200. 
  1141.     I know this is stupid but this utility is for me, and this is what I
  1142.     use. If someone is persistant enough and sends me the code for figuring
  1143.     out the current screen size...
  1144.  
  1145. RELEASE HISTORY:
  1146.  
  1147.     V1.0    Initial release. (Only jdow saw this)
  1148.     V1.1    Bug fixes to the Arexx port. No major changes from V1.0
  1149.  
  1150.     V1.2    Major new release. Lots of changes and additions.
  1151.  
  1152.             1.  It's harder to hang flist from the REXX port
  1153.                 (I haven't been able to do it yet)
  1154.  
  1155.             2.  New REXX Commands:
  1156.                 makedir     - make a new directory
  1157.                 changedir   - change to a directory eg:
  1158.                               'changedir flist'
  1159.                 rename      - rename a file using string requestor.
  1160.                 redraw      - redraw the screen.
  1161.                 request     - bring up the ARP requestor.
  1162.  
  1163.             3.  Menu support (and shortcuts) for all keystrokes.
  1164.                 (as well as an attempt at extended selection support)
  1165.  
  1166.             4.  New commands added:
  1167.                 makedir
  1168.                 execute rexx macro (via string requestor)
  1169.                 rename file
  1170.                 sort by pattern
  1171.                 sort by date.
  1172.                 sort by day.
  1173.  
  1174.             5.  Bug fixes to cursor movment routines, as well as adding
  1175.                 cntrl-U (erase line). Also insert mode is now the only 
  1176.                 mode of entry.
  1177.             
  1178.             6.  Supports SHIFT-UP and SHIFT-DOWN cursor keys to move
  1179.                 10 lines up or down the list. Also SHIFT left, right
  1180.                 to move to the begining or the end of the line respectively.
  1181.  
  1182.             7.  Uses default screen colors.
  1183.  
  1184.             8.  Internal changes to static memory allocation for 
  1185.                 efficiency. In other words, it uses less memory.
  1186.  
  1187.             9.  Fixed misterious bug causing the original CLI to 
  1188.                 generate a Software Error. All better now.
  1189.  
  1190. swb 1/23/89
  1191.  
  1192. Flist is a BeerWare product of 'The Checkered Ball'
  1193. SHAR_EOF
  1194. cat << \SHAR_EOF > rexxglue.asm
  1195. * === rexxglue.asm =====================================================
  1196. *
  1197. * Copyright (c) 1986, 1987 by William S. Hawes (All Rights Reserved)
  1198. *
  1199. * ======================================================================
  1200. * "Glue" routines for calling functions in the ARexx Systems Library.
  1201. * All calls assume that the external _RexxSysBase has been set to the
  1202. * ARexx SYstems library base by a call to OpenLibrary.
  1203.  
  1204.          INCLUDE  "rexx/storage.i"
  1205.          INCLUDE  "rexx/rxslib.i"
  1206.  
  1207.          XREF     _RexxSysBase
  1208.  
  1209. * First calling convention:
  1210. * 1, 2, or 3 parameters in (A0,A1,D0), return value in D0.
  1211.  
  1212.          ; node = AddClipNode(&header,&name,value,length)
  1213.  
  1214.          XDEF     _AddClipNode
  1215. _AddClipNode:
  1216.          move.w   #_LVOAddClipNode,d1
  1217.          bra      CallSeq1
  1218.  
  1219.          ; node = AddRsrcNode(&header,&name,size)
  1220.  
  1221.          XDEF     _AddRsrcNode
  1222. _AddRsrcNode:
  1223.          move.w   #_LVOAddRsrcNode,d1
  1224.          bra      CallSeq1
  1225.  
  1226.          ; count = CloseF(filehandle)
  1227.  
  1228.          XDEF     _CloseF
  1229. _CloseF
  1230.          move.w   #_LVOCloseF,d1
  1231.          bra.s    CallSeq1
  1232.  
  1233.          ; test = CmpString(&string1,&string2)
  1234.  
  1235.          XDEF     _CmpString
  1236. _CmpString:
  1237.          move.w   #_LVOCmpString,d1
  1238.          bra.s    CallSeq1
  1239.  
  1240.          ; envptr = CurrentEnv(rxtptr)
  1241.  
  1242.          XDEF     _CurrentEnv
  1243. _CurrentEnv:
  1244.          moveq    #_LVOCurrentEnv,d1
  1245.          bra.s    CallSeq1
  1246.  
  1247.          ; error = CVc2x(&buffer,&string,length)
  1248.  
  1249.          XDEF     _CVc2x
  1250. _CVc2x:
  1251.          move.w   #_LVOCVc2x,d1
  1252.          bra.s    CallSeq1
  1253.  
  1254.          ; error = CVx2c(&buffer,&string,length)
  1255.  
  1256.          XDEF     _CVx2c
  1257. _CVx2c:
  1258.          move.w   #_LVOCVx2c,d1
  1259.          bra.s    CallSeq1
  1260.  
  1261.          ; ClosePublicPort(&header,&name)
  1262.  
  1263.          XDEF     _ClosePublicPort
  1264. _ClosePublicPort:
  1265.          move.w   #_LVOClosePublicPort,d1
  1266.          bra.s    CallSeq1
  1267.  
  1268.          ; spptr = CreateDOSPkt()
  1269.  
  1270.          XDEF     _CreateDOSPkt
  1271. _CreateDOSPkt:
  1272.          move.w   #_LVOCreateDOSPkt,d1
  1273.          bra.s    CallSeq1
  1274.  
  1275.          ; msgptr = CreateRexxMsg(&replyport,&fileext,&hostname)
  1276.  
  1277.          XDEF     _CreateRexxMsg
  1278. _CreateRexxMsg:
  1279.          move.w   #_LVOCreateRexxMsg,d1
  1280.          bra.s    CallSeq1
  1281.  
  1282.          ; DeleteArgstring(argptr)
  1283.  
  1284.          XDEF     _DeleteArgstring
  1285. _DeleteArgstring:
  1286.          move.w   #_LVODeleteArgstring,d1
  1287.          bra.s    CallSeq1
  1288.  
  1289.          ; DeleteRexxMsg(msgptr)
  1290.  
  1291.          XDEF     _DeleteRexxMsg
  1292. _DeleteRexxMsg:
  1293.          move.w   #_LVODeleteRexxMsg,d1
  1294.          bra.s    CallSeq1
  1295.  
  1296.          ; code = DOSCommand(&string,filehandle)
  1297.  
  1298.          XDEF     _DOSCommand
  1299. _DOSCommand:
  1300.          move.w   #_LVODOSCommand,d1
  1301.          bra.s    CallSeq1
  1302.  
  1303.          ; count = DOSRead(filehandle,&buffer,length)
  1304.  
  1305.          XDEF     _DOSRead
  1306. _DOSRead:
  1307.          move.w   #_LVODOSRead,d1
  1308.          bra.s    CallSeq1
  1309.  
  1310.          ; count = DOSWrite(filehandle,&buffer,length)
  1311.  
  1312.          XDEF     _DOSWrite
  1313. _DOSWrite:
  1314.          move.w   #_LVODOSWrite,d1
  1315.          bra.s    CallSeq1
  1316.  
  1317.          ; DeleteDOSPkt(&stdpkt)
  1318.  
  1319.          XDEF     _DeleteDOSPkt
  1320. _DeleteDOSPkt:
  1321.          move.w   #_LVODeleteDOSPkt,d1
  1322.          bra.s    CallSeq1
  1323.  
  1324.          ; count = ExistF(filehandle,&buffer,length)
  1325.  
  1326.          XDEF     _ExistF
  1327. _ExistF:
  1328.          move.w   #_LVOExistF,d1
  1329.          bra.s    CallSeq1
  1330.  
  1331.          ; devptr = FindDevice(&name)
  1332.  
  1333.          XDEF     _FindDevice
  1334. _FindDevice:
  1335.          move.w   #_LVOFindDevice,d1
  1336.          bra.s    CallSeq1
  1337.  
  1338.          ; FreeSpace(envptr,memptr,length)
  1339.  
  1340.          XDEF     _FreeSpace
  1341. _FreeSpace:
  1342.          moveq    #_LVOFreeSpace,d1
  1343.          bra.s    CallSeq1
  1344.  
  1345.          ; FreePort(&msgport)
  1346.  
  1347.          XDEF     _FreePort
  1348. _FreePort:
  1349.          move.w   #_LVOFreePort,d1
  1350.          bra.s    CallSeq1
  1351.  
  1352.          ; type = IsSymbol(&string)
  1353.  
  1354.          XDEF     _IsSymbol
  1355. _IsSymbol:
  1356.          moveq    #_LVOIsSymbol,d1
  1357.          bra.s    CallSeq1
  1358.  
  1359.          ; InitList(&header)
  1360.  
  1361.          XDEF     _InitList
  1362. _InitList:
  1363.          move.w   #_LVOInitList,d1
  1364.          bra.s    CallSeq1
  1365.  
  1366.          ; signal = InitPort(&replyport)
  1367.  
  1368.          XDEF     _InitPort
  1369. _InitPort:
  1370.          move.w   #_LVOInitPort,d1
  1371.          bra.s    CallSeq1
  1372.  
  1373.          ; boolean = IsRexxMsg(msgptr)
  1374.  
  1375.          XDEF     _IsRexxMsg
  1376. _IsRexxMsg:
  1377.          move.w   #_LVOIsRexxMsg,d1
  1378.          bra.s    CallSeq1
  1379.  
  1380.          ; length = LengthArgstring(argptr)
  1381.  
  1382.          XDEF     _LengthArgstring
  1383. _LengthArgstring:
  1384.          move.w   #_LVOLengthArgstring,d1
  1385.  
  1386.          ; Load three arguments into (A0,A1,D0)
  1387.  
  1388. CallSeq1 movea.l  4(sp),a0
  1389.          movea.l  8(sp),a1
  1390.          move.l   12(sp),d0
  1391.  
  1392.          ; Call the library function
  1393.  
  1394. CallFunc move.l   a6,-(sp)
  1395.          movea.l  _RexxSysBase,a6
  1396.          jsr      0(a6,d1.w)
  1397.          movea.l  (sp)+,a6
  1398.          rts
  1399.  
  1400.          ; argptr = ListNames(&header)
  1401.  
  1402.          XDEF     _ListNames
  1403. _ListNames:
  1404.          move.w   #_LVOListNames,d1
  1405.          bra.s    CallSeq1
  1406.  
  1407.          ; iobptr = OpenF(filehandle,&buffer,length)
  1408.  
  1409.          XDEF     _OpenF
  1410. _OpenF:
  1411.          move.w   #_LVOOpenF,d1
  1412.          bra.s    CallSeq1
  1413.  
  1414.          ; nodeptr = OpenPublicPort(&header,&name)
  1415.  
  1416.          XDEF     _OpenPublicPort
  1417. _OpenPublicPort:
  1418.          move.w   #_LVOOpenPublicPort,d1
  1419.          bra.s    CallSeq1
  1420.  
  1421.          ; count = QueueF(filehandle,&buffer,length)
  1422.  
  1423.          XDEF     _QueueF
  1424. _QueueF:
  1425.          move.w   #_LVOQueueF,d1
  1426.          bra.s    CallSeq1
  1427.  
  1428.          ; count = ReadF(filehandle,&buffer,length)
  1429.  
  1430.          XDEF     _ReadF
  1431. _ReadF:
  1432.          move.w   #_LVOReadF,d1
  1433.          bra.s    CallSeq1
  1434.  
  1435.          ; count = ReadStr(filehandle,&buffer,length)
  1436.  
  1437.          XDEF     _ReadStr
  1438. _ReadStr:
  1439.          move.w   #_LVOReadStr,d1
  1440.          bra.s    CallSeq1
  1441.  
  1442.          ; RemRsrcList(&header)
  1443.  
  1444.          XDEF     _RemRsrcList
  1445. _RemRsrcList:
  1446.          move.w   #_LVORemRsrcList,d1
  1447.          bra.s    CallSeq1
  1448.  
  1449.          ; RemRsrcNode(&header,&node)
  1450.  
  1451.          XDEF     _RemRsrcNode
  1452. _RemRsrcNode:
  1453.          move.w   #_LVORemRsrcNode,d1
  1454.          bra.s    CallSeq1
  1455.  
  1456.          ; RemClipNode(&header,&node)
  1457.  
  1458.          XDEF     _RemClipNode
  1459. _RemClipNode:
  1460.          move.w   #_LVORemClipNode,d1
  1461.          bra.s    CallSeq1
  1462.  
  1463.          ; test = StrcmpN(&string1,&string2)
  1464.  
  1465.          XDEF     _StrcmpN
  1466. _StrcmpN:
  1467.          move.w   #_LVOStrcmpN,d1
  1468.          bra.s    CallSeq1
  1469.  
  1470.          ; test = StrcmpU(&string1,&string2)
  1471.  
  1472.          XDEF     _StrcmpU
  1473. _StrcmpU:
  1474.          move.w   #_LVOStrcmpU,d1
  1475.          bra.s    CallSeq1
  1476.  
  1477.          ; test = StrcpyA(&string1,&string2)
  1478.  
  1479.          XDEF     _StrcpyA
  1480. _StrcpyA:
  1481.          move.w   #_LVOStrcpyA,d1
  1482.          bra.s    CallSeq1
  1483.  
  1484.          ; test = StrcpyN(&string1,&string2)
  1485.  
  1486.          XDEF     _StrcpyN
  1487. _StrcpyN:
  1488.          move.w   #_LVOStrcpyN,d1
  1489.          bra.s    CallSeq1
  1490.  
  1491.          ; test = StrcpyU(&string1,&string2)
  1492.  
  1493.          XDEF     _StrcpyU
  1494. _StrcpyU:
  1495.          move.w   #_LVOStrcpyU,d1
  1496.          bra.s    CallSeq1
  1497.  
  1498.          ; length = Strlen(&string)
  1499.  
  1500.          XDEF     _Strlen
  1501. _Strlen:
  1502.          move.w   #_LVOStrlen,d1
  1503.          bra.s    CallSeq1
  1504.  
  1505.          ; count = SeekF(filehandle,&buffer,length)
  1506.  
  1507.          XDEF     _SeekF
  1508. _SeekF:
  1509.          move.w   #_LVOSeekF,d1
  1510.          bra.s    CallSeq1
  1511.  
  1512.          ; count = StackF(filehandle,&buffer,length)
  1513.  
  1514.          XDEF     _StackF
  1515. _StackF:
  1516.          move.w   #_LVOStackF,d1
  1517.          bra      CallSeq1
  1518.  
  1519.          ; count = WriteF(filehandle,&buffer,length)
  1520.  
  1521.          XDEF     _WriteF
  1522. _WriteF:
  1523.          move.w   #_LVOWriteF,d1
  1524.          bra      CallSeq1
  1525.  
  1526. * Second calling convention:  2 parameters in (A0,D0), return value in D0.
  1527.  
  1528.          ; argptr = CreateArgstring(&string,length)
  1529.  
  1530.          XDEF     _CreateArgstring
  1531. _CreateArgstring:
  1532.          moveq    #_LVOCreateArgstring,d1
  1533.          bra.s    CallSeq2
  1534.  
  1535.          ; ClearMem(address,length)
  1536.  
  1537.          XDEF     _ClearMem
  1538. _ClearMem:
  1539.          move.w   #_LVOClearMem,d1
  1540.          bra.s    CallSeq2
  1541.  
  1542.          ; count = ClearRexxMsg(msgptr,count)
  1543.  
  1544.          XDEF     _ClearRexxMsg
  1545. _ClearRexxMsg:
  1546.          move.w   #_LVOClearRexxMsg,a1
  1547.          bra.s    CallSeq2
  1548.  
  1549.          ; nodeptr = FindRsrcNode(&header,type)
  1550.  
  1551.          XDEF     _FindRsrcNode
  1552. _FindRsrcNode:
  1553.          move.w   #_LVOFindRsrcNode,d1
  1554.          bra.s    CallSeq2
  1555.  
  1556.          ; block = GetSpace(envptr,size)
  1557.  
  1558.          XDEF     _GetSpace
  1559. _GetSpace:
  1560.          moveq    #_LVOGetSpace,d1
  1561.          bra.s    CallSeq2
  1562.  
  1563.          ; test = StrFlipN(&string1,length)
  1564.  
  1565.          XDEF     _StrflipN
  1566. _StrflipN:
  1567.          move.w   #_LVOStrflipN,d1
  1568.  
  1569.          ; Load two arguments (A0,D0)
  1570.  
  1571. CallSeq2 movea.l  4(sp),a0
  1572.          move.l   8(sp),d0
  1573.          bra      CallFunc
  1574.  
  1575. * Third calling convention:  1 parameter in D0, return value in D0.
  1576.  
  1577.          ; argptr = CVi2arg(value)
  1578.  
  1579.          XDEF     _CVi2arg
  1580. _CVi2arg:
  1581.          move.w   #_LVOCVi2arg,d1
  1582.          bra.s    CallSeq3
  1583.  
  1584.          ; LockRexxBase(resource)
  1585.  
  1586.          XDEF     _LockRexxBase
  1587. _LockRexxBase:
  1588.          move.w   #_LVOLockRexxBase,d1
  1589.          bra.s    CallSeq3
  1590.  
  1591.          ; char = ToUpper(char)
  1592.  
  1593.          XDEF     _ToUpper
  1594. _ToUpper:
  1595.          move.w   #_LVOToUpper,d1
  1596.          bra.s    CallSeq3
  1597.  
  1598.          ; UnlockRexxBase(resource)
  1599.  
  1600.          XDEF     _UnlockRexxBase
  1601. _UnlockRexxBase:
  1602.          move.w   #_LVOUnlockRexxBase,d1
  1603.  
  1604.          ; Load one argument in D0
  1605.  
  1606. CallSeq3 move.l   4(sp),d0
  1607.          bra      CallFunc
  1608.  
  1609. * Fourth calling sequence:  3 parameters in (A0,D0,D1), return value in D0.
  1610.  
  1611.          ; value = CVi2a(&buffer,value,length)
  1612.  
  1613.          XDEF     _CVi2a
  1614. _CVi2a:
  1615.          move.w   #_LVOCVi2a,a1
  1616.          bra.s    CallSeq4
  1617.  
  1618.          ; boolean = FillRexxMsg(msgptr,count,mask)
  1619.  
  1620.          XDEF     _FillRexxMsg
  1621. _FillRexxMsg:
  1622.          move.w   #_LVOFillRexxMsg,a1
  1623.  
  1624. CallSeq4 movea.l  4(sp),a0
  1625.          move.l   8(sp),d0
  1626.          move.l   12(sp),d1
  1627.  
  1628.          ; Call the library function
  1629.  
  1630.          move.l   a6,-(sp)
  1631.          movea.l  _RexxSysBase,a6
  1632.          jsr      0(a6,a1.w)
  1633.          movea.l  (sp)+,a6
  1634.          rts
  1635.  
  1636. * Special calling sequences for multiple returns.
  1637.  
  1638.          ; value = CVa2i(&string,&digits)
  1639.  
  1640.          XDEF     _CVa2i
  1641. _CVa2i:
  1642.          movea.l  4(sp),a0             ; scan pointer
  1643.          move.w   #_LVOCVa2i,d1
  1644.          bsr      CallFunc             ; D0=converted value
  1645.          movea.l  8(sp),a1             ; return pointer
  1646.          move.l   d1,(a1)              ; digits scanned
  1647.          rts
  1648.  
  1649.          ; boolean = ErrorMsg(code,&ssptr)
  1650.  
  1651.          XDEF     _ErrorMsg
  1652. _ErrorMsg:
  1653.          move.l   4(sp),d0
  1654.          moveq    #_LVOErrorMsg,d1
  1655.          bsr      CallFunc             ; D0=boolean  A0=string structure
  1656.          movea.l  8(sp),a1             ; return pointer
  1657.          move.l   a0,(a1)              ; string structure
  1658.          rts
  1659.  
  1660.          END
  1661. SHAR_EOF
  1662. cat << \SHAR_EOF > rexxport.c
  1663. /*
  1664.  
  1665.     This module is responsible for communicating with Rexx.
  1666.     Specifically it opens a message port and tells rexx to execute
  1667.     a program. Rexx should signal host of errors or death.
  1668.  
  1669. */
  1670.  
  1671. #include <rexx/storage.h>
  1672. #include <rexx/rxslib.h>
  1673. #include <rexx/errors.h>
  1674. #include "flist.h"
  1675.  
  1676. /* system types */
  1677.  
  1678. extern void ClearMem(),AddPort(),FreePort(),InitPort(),RemPort(),Forbid();
  1679. extern void Permit();
  1680. extern LONG OpenLibrary();
  1681. extern struct RexxMsg *GetMsg();
  1682. extern struct RexxMsg myrexxport;
  1683. extern struct Library *RexxSysBase;
  1684. extern void control_keys();
  1685.  
  1686. /* My stuff */
  1687.  
  1688. struct FileHandle *fh;
  1689. struct RexxMsg *rxmsg;
  1690. extern char strbuf[256];
  1691. extern long collum, row, line, first, top;
  1692.  
  1693. #define PUBFAST MEMF_FAST+MEMF_PUBLIC+MEMF_CLEAR
  1694.  
  1695. void OpenRexxPort(string,port)
  1696. char *string;
  1697. struct MsgPort *port;
  1698. {
  1699.  
  1700.     ClearMem(port,(LONG)sizeof(struct MsgPort));
  1701.     InitPort(port,string);
  1702.     AddPort(port);
  1703. }
  1704.  
  1705. void DeleteRexxPort(port)
  1706. struct MsgPort *port;
  1707. {
  1708.     if(port != NULL){
  1709.         RemPort(port);
  1710.         FreePort(port);
  1711.     }
  1712. }
  1713.  
  1714. struct RexxMsg *PollRexxPort(port)
  1715. struct MsgPort *port;
  1716. {
  1717.     struct RexxMsg *rxport;
  1718.  
  1719.     rxport = GetMsg(port);
  1720.     return(rxport);
  1721.  
  1722. }
  1723.  
  1724. struct RexxMsg *WaitRexxPort(port)
  1725. struct MsgPort *port;
  1726. {
  1727.  
  1728.     WaitPort(port);
  1729.     return(PollRexxPort(port));
  1730. }
  1731.  
  1732. void CleanupRexx()
  1733. {
  1734.  
  1735. /*    Close(fh); */
  1736.     DeleteArgstring(rxmsg->rm_Args[0]);
  1737.     DeleteRexxMsg(rxmsg);
  1738. }
  1739.  
  1740. long StartRexxProg(rexport)
  1741. struct MsgPort *rexport;
  1742. {
  1743.     struct MsgPort *port;
  1744.     struct Window *strptr;
  1745.  
  1746.     strbuf[0] = '\0';
  1747.     strptr = make_gadget("Enter the REXX macro name ");
  1748.  
  1749.     if (strptr == NULL) {
  1750.         auto_req("Couldn't open Requestor!");
  1751.         return FALSE;
  1752.     }
  1753.  
  1754.     wait_for_event(strptr); 
  1755.  
  1756.     if (strbuf[0] == '\0') {
  1757.         return FALSE;
  1758.     }
  1759.  
  1760.     rxmsg = CreateRexxMsg(rexport,"flex","flport");
  1761.     rxmsg->rm_Args[0] = strbuf;
  1762.     rxmsg->rm_Action = RXCOMM;
  1763. /*    rxmsg->rm_Stdout = Output(); */
  1764.  
  1765.     if(!FillRexxMsg(rxmsg, 1L, 0L)) {
  1766.         DeleteRexxMsg(rxmsg);
  1767.         return FALSE;
  1768.     }
  1769.  
  1770.     Forbid();
  1771.     port = (struct RexxMsg *)FindPort("REXX");
  1772.     if(port == NULL){
  1773.         Permit();
  1774.         auto_req("REXX is not here!");
  1775.         CleanupRexx();
  1776.         return FALSE;
  1777.     }
  1778.  
  1779.     PutMsg(port,rxmsg);         /* email in it's truest form */
  1780.     Permit();
  1781.     return TRUE;
  1782. }
  1783.  
  1784. char *rexx_strings[] = {
  1785.     "end",
  1786.     "iconify",
  1787.     "sort s",
  1788.     "sort z",
  1789.     "sort t",
  1790.     "sort o",
  1791.     "parent",
  1792.     "redraw",
  1793.     "reget",
  1794.     "request",
  1795.     "makedir",
  1796.     "changedir",
  1797.     "sort y"
  1798. };
  1799.  
  1800. dorexx()
  1801. {
  1802.     struct RexxMsg *resultmsg;
  1803.     char buf[256];
  1804.     int equal, i;
  1805.                 
  1806.     if(RexxSysBase == NULL){
  1807.         auto_req(" Rexx library not Available");
  1808.         return;
  1809.     }
  1810.  
  1811.     if(!StartRexxProg(&myrexxport)){    /* start up fl.flex as a rexx task */
  1812.         if (strbuf[0] != '\0')
  1813.             auto_req(" PANIC - couldn't start up rexx program!");
  1814.         return;
  1815.     }
  1816.  
  1817.     /* this is a communication test ... */
  1818.  
  1819.     for(;;) {
  1820.  
  1821.         resultmsg = WaitRexxPort(&myrexxport);
  1822.  
  1823. #ifdef DEBUG
  1824.         sprintf(buf,"Return of -%d- , -%s-",resultmsg->rm_Result1,resultmsg->rm_Args[0]);
  1825.         auto_req(buf);
  1826. #endif
  1827.  
  1828.         if (resultmsg->rm_Result1 > 0) {
  1829.  
  1830.             if (Strcmp(strbuf, resultmsg->rm_Args[0]) == 0) {
  1831.                 sprintf(buf,"Error %d in -%s.flex-.",
  1832.                     resultmsg->rm_Result1,strbuf);
  1833.                 auto_req(buf);
  1834.                 resultmsg->rm_Result1 = 5; 
  1835.                 resultmsg->rm_Result2 = 0; 
  1836.                 CleanupRexx();
  1837.                 return;
  1838.             }
  1839.         }
  1840.  
  1841.         resultmsg->rm_Result1 = 0;  /* no error  */
  1842.         resultmsg->rm_Result2 = 0;  /* no secondary */
  1843.  
  1844.         for(i=0;i<13;i++){
  1845.             equal = Strncmp(resultmsg->rm_Args[0],rexx_strings[i],
  1846.                         strlen(rexx_strings[i]));
  1847.             if (equal == 0)
  1848.                 break;
  1849.         }
  1850.  
  1851. #ifdef DEBUG
  1852.         sprintf(buf,"I = %d, string is %s",i,rexx_strings[i]);
  1853.         auto_req(buf);
  1854. #endif
  1855.  
  1856.         blankcur();
  1857.         switch (i) {
  1858.         
  1859.             case 0:
  1860.                 ReplyMsg(resultmsg);        /* send back 'end' message */
  1861.                 WaitRexxPort(&myrexxport);  /* wait for original Msg to ret */
  1862.                 CleanupRexx();
  1863.                 return;
  1864.  
  1865.             case 1:         /* Iconify */
  1866.                 tticon();
  1867.                 break;
  1868.  
  1869.             case 2:         /* sort by name */
  1870.                 sort(0);
  1871.                 refresh();
  1872.                 break;
  1873.  
  1874.             case 3:         /* sort by size */
  1875.                 sort(1);
  1876.                 refresh();
  1877.                 break;
  1878.  
  1879.             case 4:         /* sort by time */
  1880.                 sort(2);
  1881.                 refresh();
  1882.                 break;
  1883.  
  1884.             case 5:         /* sort by pattern */
  1885.                 sort(3);
  1886.                 refresh();
  1887.                 break;
  1888.  
  1889.             case 6:         /* get parent dir */
  1890.                 parent();
  1891.                 refresh();
  1892.                 break;
  1893.  
  1894.             case 7:         /* redraw screen */
  1895.                 control_keys(0x0c);
  1896.                 break;
  1897.  
  1898.             case 8:         /* reget directory */
  1899.                 getdir();
  1900.                 refresh();
  1901.                 break;
  1902.  
  1903.             case 9:
  1904.                 control_keys(0x01); /* ARP requestor */
  1905.                 break;
  1906.  
  1907.             case 10:
  1908.                 control_keys(0x0e); /* Makedir */
  1909.                 break;
  1910.  
  1911.             case 11:                /* changedir 'string' */
  1912.                 if (strlen(resultmsg->rm_Args[0]) > 10) {
  1913. #ifdef DEBUG
  1914.                     auto_req(&resultmsg->rm_Args[0][10]);
  1915. #endif
  1916.                     strcpy(buf,&resultmsg->rm_Args[0][10]);
  1917.                     changedir(buf);
  1918.                     refresh();
  1919.                 } else
  1920.                     auto_req("Bad arguments to CHANGEDIR.");
  1921.                 break;
  1922.  
  1923.             case 12:         /* sort by day */
  1924.                 sort(4);
  1925.                 refresh();
  1926.                 break;
  1927.  
  1928.             default:
  1929.                 resultmsg->rm_Result1 = 5;  /* shows an error code */
  1930.                 resultmsg->rm_Result2 = 0;  /* no secondary        */
  1931.  
  1932.                 if (Strcmp(strbuf, resultmsg->rm_Args[0]) == 0) {
  1933.                     sprintf(buf,"End keyword not found in -%s.flex-.",
  1934.                         strbuf);
  1935.                     auto_req(buf);
  1936.                     ReplyMsg(resultmsg);
  1937.                     WaitRexxPort(&myrexxport);
  1938.                     CleanupRexx();
  1939.                     return;
  1940.                 }
  1941.                 sprintf(buf,"Bad command -%s- from macro %s.flex",
  1942.                     resultmsg->rm_Args[0],strbuf);
  1943.                 auto_req(buf);
  1944.                 break;
  1945.         }
  1946.         ReplyMsg(resultmsg);
  1947.         drawcur();
  1948.     }   /* end of forever */
  1949. }
  1950. SHAR_EOF
  1951. #    End of shell archive
  1952. exit 0
  1953. -- 
  1954. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1955. Have five nice days.
  1956.